package icu.cqcai.xinsi.service;

import icu.cqcai.xinsi.domain.ChatMessage;
import icu.cqcai.xinsi.domain.ChatSession;
import icu.cqcai.xinsi.domain.User;
import icu.cqcai.xinsi.mapper.ChatMessageMapper;
import icu.cqcai.xinsi.mapper.ChatSessionMapper;
import icu.cqcai.xinsi.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 聊天服务类 - 整合数据库存储和AI对话
 */
@Service
public class ChatService {

    @Autowired
    private ChatSessionMapper chatSessionMapper;

    @Autowired
    private ChatMessageMapper chatMessageMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CozeApiService cozeApiService;

    /**
     * 发送消息并获取AI回复（支持上下文）
     * @param username 用户名
     * @param message 用户消息
     * @return AI回复
     */
    @Transactional
    public String sendMessage(String username, String message) {
        try {
            // 1. 获取或创建用户
            User user = userMapper.findByUsername(username);
            if (user == null) {
                // 如果是匿名用户，创建临时用户记录
                user = createAnonymousUser(username);
            }

            // 2. 获取或创建会话
            ChatSession session = getOrCreateSession(user.getId(), message, username);

            // 3. 保存用户消息
            ChatMessage userMessage = new ChatMessage(
                session.getId(), 
                user.getId(), 
                "user", 
                message, 
                session.getCozeUserId()
            );
            chatMessageMapper.insertChatMessage(userMessage);

            // 4. 获取用户最近3小时内的所有对话记录（用于上下文）
            List<ChatMessage> historyMessages = getRecentUserMessages(user.getId(), 3, 10);
            
            // 5. 构建包含历史对话的完整消息
            String messageWithContext = buildMessageWithContext(message, historyMessages);

            // 6. 调用扣子API获取回复（使用简单的sendMessage方法）
            long startTime = System.currentTimeMillis();
            String aiResponse = cozeApiService.sendMessage(
                messageWithContext, 
                session.getCozeUserId(), 
                session.getCozeConversationId()
            );
            long responseTime = System.currentTimeMillis() - startTime;

            // 7. 保存AI回复
            ChatMessage aiMessage = new ChatMessage(
                session.getId(), 
                user.getId(), 
                aiResponse, 
                responseTime, 
                session.getCozeUserId()
            );
            chatMessageMapper.insertChatMessage(aiMessage);

            // 8. 更新会话信息
            updateSessionInfo(session.getId());

            return aiResponse;

        } catch (Exception e) {
            System.err.println("发送消息失败: " + e.getMessage());
            e.printStackTrace();
            return "抱歉，服务暂时不可用，请稍后重试。";
        }
    }

    /**
     * 发送带文件的消息并获取AI回复
     * @param username 用户名
     * @param userMessage 用户消息
     * @param file 附件文件
     * @return AI回复
     */
    @Transactional
    public String sendMessageWithFile(String username, String userMessage, MultipartFile file) {
        try {
            // 1. 获取或创建用户
            User user = userMapper.findByUsername(username);
            if (user == null) {
                user = createAnonymousUser(username);
            }

            // 2. 获取或创建会话
            ChatSession session = getOrCreateSession(user.getId(), userMessage, username);

            // 3. 保存用户消息
            ChatMessage userChatMessage = new ChatMessage(
                session.getId(), 
                user.getId(), 
                "user", 
                userMessage, 
                session.getCozeUserId()
            );
            chatMessageMapper.insertChatMessage(userChatMessage);

            // 4. 获取用户最近3小时内的所有对话记录（用于上下文）
            List<ChatMessage> historyMessages = getRecentUserMessages(user.getId(), 3, 10);

            // 5. 上传文件到阿里云OSS并调用AI
            long startTime = System.currentTimeMillis();
            String fileUrl = cozeApiService.uploadFileToOSS(file);
            String aiResponse;
            
            if (fileUrl != null && !fileUrl.isEmpty()) {
                // 构建包含文件和历史对话的完整消息
                String messageWithFile = userMessage + "\n\n请访问以下链接查看文件内容：" + fileUrl;
                String messageWithContext = buildMessageWithContext(messageWithFile, historyMessages);
                aiResponse = cozeApiService.sendMessage(
                    messageWithContext, 
                    session.getCozeUserId(), 
                    session.getCozeConversationId()
                );
            } else {
                aiResponse = "文件上传失败，请检查文件格式是否正确。";
            }
            
            long responseTime = System.currentTimeMillis() - startTime;

            // 6. 保存AI回复
            ChatMessage aiMessage = new ChatMessage(
                session.getId(), 
                user.getId(), 
                aiResponse, 
                responseTime, 
                session.getCozeUserId()
            );
            chatMessageMapper.insertChatMessage(aiMessage);

            // 7. 更新会话信息
            updateSessionInfo(session.getId());

            return aiResponse;

        } catch (Exception e) {
            System.err.println("带文件消息发送失败: " + e.getMessage());
            e.printStackTrace();
            return "抱歉，文件处理暂时不可用，请稍后重试。";
        }
    }

    /**
     * 获取用户的聊天会话列表
     */
    public List<ChatSession> getUserSessions(String username) {
        User user = userMapper.findByUsername(username);
        if (user == null) {
            return List.of();
        }
        return chatSessionMapper.selectSessionsByUserId(user.getId());
    }

    /**
     * 获取会话的消息历史
     */
    public List<ChatMessage> getSessionMessages(Long sessionId) {
        return chatMessageMapper.selectMessagesBySessionId(sessionId);
    }

    /**
     * 获取会话的消息历史（分页）
     */
    public List<ChatMessage> getSessionMessages(Long sessionId, int page, int size) {
        int offset = (page - 1) * size;
        return chatMessageMapper.selectMessagesBySessionIdWithPage(sessionId, offset, size);
    }

    /**
     * 删除会话
     */
    @Transactional
    public boolean deleteSession(Long sessionId) {
        try {
            // 软删除会话
            chatSessionMapper.deleteSession(sessionId, LocalDateTime.now());
            // 软删除会话的所有消息
            chatMessageMapper.deleteMessagesBySessionId(sessionId);
            return true;
        } catch (Exception e) {
            System.err.println("删除会话失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 搜索用户的聊天记录
     */
    public List<ChatMessage> searchMessages(String username, String keyword, int limit) {
        User user = userMapper.findByUsername(username);
        if (user == null) {
            return List.of();
        }
        return chatMessageMapper.searchMessagesByContent(user.getId(), keyword, limit);
    }

    /**
     * 获取用户的聊天统计信息
     */
    public ChatStatistics getUserChatStatistics(String username) {
        User user = userMapper.findByUsername(username);
        if (user == null) {
            return new ChatStatistics(0, 0);
        }

        int sessionCount = chatSessionMapper.countActiveSessionsByUserId(user.getId());
        int messageCount = chatMessageMapper.countMessagesByUserId(user.getId());
        
        return new ChatStatistics(sessionCount, messageCount);
    }

    /**
     * 获取或创建聊天会话（支持上下文）
     */
    private ChatSession getOrCreateSession(Long userId, String firstMessage, String username) {
        // 获取用户最近的活跃会话
        ChatSession latestSession = chatSessionMapper.selectLatestSessionByUserId(userId);
        
        // 如果有最近的活跃会话，继续使用（不限制日期，保持长期上下文）
        if (latestSession != null && latestSession.getStatus() == 1) {
            return latestSession;
        }
        
        // 否则创建新会话
        String title = generateSessionTitle(firstMessage);
        String cozeUserId = generateFixedCozeUserId(username); // 使用固定的coze_user_id
        ChatSession newSession = new ChatSession(userId, title);
        newSession.setCozeUserId(cozeUserId);
        // conversation_id 将在第一次API调用时由Coze返回并更新
        
        chatSessionMapper.insertChatSession(newSession);
        return newSession;
    }

    /**
     * 获取用户最近几小时内的消息（用于上下文）
     */
    private List<ChatMessage> getRecentUserMessages(Long userId, int hours, int limit) {
        return chatMessageMapper.selectRecentMessagesByUserIdAndHours(userId, hours, limit);
    }

    /**
     * 生成固定的Coze用户ID（每个用户唯一且固定）
     */
    private String generateFixedCozeUserId(String username) {
        // 为每个用户生成固定的Coze用户ID，基于用户名的哈希值，确保同一用户始终使用相同ID
        return "xinsi_" + username + "_" + Math.abs(username.hashCode());
    }

    /**
     * 创建匿名用户
     */
    private User createAnonymousUser(String username) {
        User anonymousUser = new User();
        anonymousUser.setUsername(username);
        anonymousUser.setPassword(""); // 匿名用户无密码
        anonymousUser.setEmail("");
        anonymousUser.setPhone("");
        anonymousUser.setStatus(1);
        anonymousUser.setCreateTime(LocalDateTime.now());
        anonymousUser.setUpdateTime(LocalDateTime.now());
        
        userMapper.insert(anonymousUser);
        return anonymousUser;
    }

    /**
     * 更新会话信息
     */
    private void updateSessionInfo(Long sessionId) {
        LocalDateTime now = LocalDateTime.now();
        chatSessionMapper.updateSessionLastMessage(sessionId, now, now);
    }

    /**
     * 生成会话标题
     */
    private String generateSessionTitle(String firstMessage) {
        if (firstMessage.length() <= 20) {
            return firstMessage;
        }
        return firstMessage.substring(0, 20) + "...";
    }

    /**
     * 创建新对话会话
     * @param username 用户名
     * @return 是否创建成功
     */
    @Transactional
    public boolean createNewSession(String username) {
        try {
            // 1. 获取或创建用户
            User user = userMapper.findByUsername(username);
            if (user == null) {
                user = createAnonymousUser(username);
            }

            // 2. 结束当前活跃会话（如果有的话）
            ChatSession currentSession = chatSessionMapper.selectLatestSessionByUserId(user.getId());
            if (currentSession != null && currentSession.getStatus() == 1) {
                // 将当前会话状态设为已结束
                chatSessionMapper.updateSessionStatus(currentSession.getId(), 0);
            }

            // 3. 创建新会话
            String title = "新对话";
            String cozeUserId = generateFixedCozeUserId(username);
            ChatSession newSession = new ChatSession(user.getId(), title);
            newSession.setCozeUserId(cozeUserId);
            
            chatSessionMapper.insertChatSession(newSession);
            return true;

        } catch (Exception e) {
            System.err.println("创建新对话失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 聊天统计信息内部类
     */
    public static class ChatStatistics {
        private final int sessionCount;
        private final int messageCount;

        public ChatStatistics(int sessionCount, int messageCount) {
            this.sessionCount = sessionCount;
            this.messageCount = messageCount;
        }

        public int getSessionCount() {
            return sessionCount;
        }

        public int getMessageCount() {
            return messageCount;
        }
    }

    /**
     * 构建包含历史对话的完整消息
     */
    private String buildMessageWithContext(String message, List<ChatMessage> historyMessages) {
        StringBuilder messageWithContext = new StringBuilder();
        
        // 如果有历史消息，先添加上下文
        if (historyMessages != null && !historyMessages.isEmpty()) {
            messageWithContext.append("=== 最近的对话记录（用于上下文参考） ===\n");
            for (ChatMessage msg : historyMessages) {
                String role = "user".equals(msg.getMessageType()) ? "用户" : "AI助手";
                messageWithContext.append(role).append(": ").append(msg.getContent()).append("\n\n");
            }
            messageWithContext.append("=== 当前问题 ===\n");
        }
        
        messageWithContext.append(message);
        return messageWithContext.toString();
    }
} 